/**
 * 按协议要求解析数据包
 * Created by macos on 14/10/28.
 */

var EventEmitter = require('events').EventEmitter;
var util = require('util');
var _ = require('lodash');
var async = require('async');

(function() {

  var root = this;
  root._buf = null;

  function MessageDecoder() {
    EventEmitter.call(this);
  }
  util.inherits(MessageDecoder, EventEmitter);

  function parserBuffer(protocol, buf, callback) {
    var callback = callback || function() {};
    var functions = [];

    //提前创建一个函数，加入解析的event
    functions.push(function(next) {
      var msg = {};
      var offset = protocol.event.length / 2;

      msg.event = protocol.event;
      return next(null, msg, offset, buf);
    });

    for (var k in protocol) {
      if (k == 'event') continue; //去除已经解析过的event

      v = protocol[k];

      if (_.isNumber(v)) {

        functions.push(async.apply(function(key, value, msg, offset, buf, next) {
          if (offset === buf.length) {
            return next(null, msg, offset, buf);
          } //如果offset等于buf长度，停止运行

          var tmpBuf = buf.slice(offset, offset + value);
          if (value === tmpBuf.length) {
            msg[key] = tmpBuf.toString('hex');
            offset = offset + value;
            return next(null, msg, offset, buf);

          } else {
            return next('error ' + key, msg)
          }

        }, k, v));

      } else if (_.isFunction(v)) {
        functions.push(v);
      }

    }

    async.waterfall(functions, function(err, msg, offset, buf) {
      if (err) {
        return callback(err, msg);
      } else {
        return callback(null, msg, offset);
      }
    });

  }

  MessageDecoder.prototype.decode = function decode(protocols, buf) {
    console.log("MessageDecoder.decode buf:", buf);

    var self = this;

    if (root._buf) {
      var len = root._buf.length + buf.length;
      buf = Buffer.concat([root._buf, buf], len);
    }

    async.whilst(
      function() {
        return buf.length > 0;
      },
      function(callback) {

        //查找协议
        var protocol;
        for (var i in protocols) {
          var protocolEvent = protocols[i].event;
          var event = buf.slice(0, protocolEvent.length / 2).toString('hex');
          if (event === protocolEvent) {
            protocol = protocols[i];
            protocol.event = protocols[i].event;
            break;
          }
        }

        //如果协议不存在，停止解析
        if (!protocol) {
          self.emit('protocolError', 'This buf can not found protocol. Buf: ' + require('util').inspect(buf));
          return;
        }

        //如果协议存在，解析
        parserBuffer(protocol, buf, function(err, msg, offset) {
          if (err) {
            var error = {};
            error.event = protocol.event;
            error.error = err;
            error.buf = buf;
            error.msg = msg;
            
            callback(error);

          } else {
            buf = buf.slice(offset);
            self.emit('decode', null, msg);
            callback();
          }

        });

      },
      function(err) {
        console.log('complete');
        if (err) {
          self.emit('decode', err);
        }
        root._buf = null;
      }
    );

  }

  module.exports = {
    MessageDecoder: MessageDecoder
  }

})();